Check GTK_WIDGET_TOPLEVEL(gtk_widget_get_toplevel (widget)), not
authorOwen Taylor <otaylor@redhat.com>
Thu, 5 Jul 2001 02:58:34 +0000 (02:58 +0000)
committerOwen Taylor <otaylor@src.gnome.org>
Thu, 5 Jul 2001 02:58:34 +0000 (02:58 +0000)
Wed Jul  4 22:35:40 2001  Owen Taylor  <otaylor@redhat.com>

* gtk/gtklabel.c gtk/gtkmenubar.c gtk/gtktreeviewcolumn.c
  gtk/gtkwidget.c:
Check GTK_WIDGET_TOPLEVEL(gtk_widget_get_toplevel (widget)),
not GTK_WIDGET_GET_ANCESTOR ... see
http://mail.gnome.org/archives/gtk-devel-list/2001-July/msg00072.html.
Indicate the best practice in the docs for gtk_widget_get_toplevel().

* gtk/gtkwidget.[ch]: Expose a private _gtk_widget_hierarchy_changed(),
so GtkPlug can give the correct signals when transforming
from a child to a toplevel.

* gtk/gtkdnd.c (gtk_drag_dest_hierarchy_changed): Handle
reparentation correctly.

* gtk/gtkwidget.c (gtk_widget_propagate_hierarchy_changed):
Propagate the previous_toplevel argument down properly.

* gtk/gtklabel.c (gtk_label_finalize): Fix unrefing
of wrong atr list.

* gtk/gtkplug.[ch]: Add an "embedded" signal.

* gtk/gtksocket.[ch]: Add "child_added", "child_removed"
signals.

* gtk/gtkplug.[ch] gtk/gtksocket.[ch]: Add
functions gtk_plug_get_id(), gtk_socket_get_id(),
to avoid the user having to worry about realization,
and gdkx.h.

* tests/testsocket.c: Extend to try out the new signals
and gtk_plug/socket_get_id().

* gtk/gtklabel.c (gtk_label_set_pattern_internal): Fix
setting of underline attributes.

* gdk/x11/gdkevents-x11.c (gdk_event_translate): Ignore
DestroyNotify events from SubstructureNotifyMask

* gdk/x11/gdkwindow-x11.c (gdk_window_reparent):
Switch GDK_WINDOW_TYPE (window) as needed.

* gdk/x11/gdkwindow-x11.c (gdk_window_new): Clean up,
allow creation of toplevel windows as children of
foreign windows.

* gtk/gtkplug.c: Remove hacks involving changing private
fields of GdkWindow.

* gtk/gtkplug.[ch] gtk/gtksocket.c: Work to make
exactly the same signals and notification
be emitted for local embedding as for inter-process
embedding.

21 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gdk/x11/gdkevents-x11.c
gdk/x11/gdkwindow-x11.c
gtk/gtkdnd.c
gtk/gtkentry.c
gtk/gtklabel.c
gtk/gtkmenubar.c
gtk/gtkplug.c
gtk/gtkplug.h
gtk/gtksocket.c
gtk/gtksocket.h
gtk/gtktreeviewcolumn.c
gtk/gtkwidget.c
gtk/gtkwidget.h
tests/testsocket.c

index 565f2a4075eed53b30aac18bc5a3517437545353..e4928ac7c302ac788cec64c31c4c6ff7338eb68f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,59 @@
+Wed Jul  4 22:35:40 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtklabel.c gtk/gtkmenubar.c gtk/gtktreeviewcolumn.c
+         gtk/gtkwidget.c:
+       Check GTK_WIDGET_TOPLEVEL(gtk_widget_get_toplevel (widget)),
+       not GTK_WIDGET_GET_ANCESTOR ... see 
+       http://mail.gnome.org/archives/gtk-devel-list/2001-July/msg00072.html.
+       Indicate the best practice in the docs for gtk_widget_get_toplevel().
+
+       * gtk/gtkwidget.[ch]: Expose a private _gtk_widget_hierarchy_changed(),
+       so GtkPlug can give the correct signals when transforming
+       from a child to a toplevel.
+       
+       * gtk/gtkdnd.c (gtk_drag_dest_hierarchy_changed): Handle
+       reparentation correctly.
+
+       * gtk/gtkwidget.c (gtk_widget_propagate_hierarchy_changed):
+       Propagate the previous_toplevel argument down properly.
+
+       * gtk/gtklabel.c (gtk_label_finalize): Fix unrefing
+       of wrong atr list.
+
+       * gtk/gtkplug.[ch]: Add an "embedded" signal.
+
+       * gtk/gtksocket.[ch]: Add "child_added", "child_removed"
+       signals.
+
+       * gtk/gtkplug.[ch] gtk/gtksocket.[ch]: Add 
+       functions gtk_plug_get_id(), gtk_socket_get_id(),
+       to avoid the user having to worry about realization,
+       and gdkx.h.
+
+       * tests/testsocket.c: Extend to try out the new signals
+       and gtk_plug/socket_get_id().
+
+       * gtk/gtklabel.c (gtk_label_set_pattern_internal): Fix
+       setting of underline attributes.
+
+       * gdk/x11/gdkevents-x11.c (gdk_event_translate): Ignore
+       DestroyNotify events from SubstructureNotifyMask
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_reparent):
+       Switch GDK_WINDOW_TYPE (window) as needed.
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_new): Clean up,
+       allow creation of toplevel windows as children of
+       foreign windows.
+
+       * gtk/gtkplug.c: Remove hacks involving changing private
+       fields of GdkWindow.
+
+       * gtk/gtkplug.[ch] gtk/gtksocket.c: Work to make 
+       exactly the same signals and notification
+       be emitted for local embedding as for inter-process
+       embedding.
+
 2001-07-04  James Henstridge  <james@daa.com.au>
 
        * gtk/gtkliststore.h: add missing gtk_list_store_newv prototype.
index 565f2a4075eed53b30aac18bc5a3517437545353..e4928ac7c302ac788cec64c31c4c6ff7338eb68f 100644 (file)
@@ -1,3 +1,59 @@
+Wed Jul  4 22:35:40 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtklabel.c gtk/gtkmenubar.c gtk/gtktreeviewcolumn.c
+         gtk/gtkwidget.c:
+       Check GTK_WIDGET_TOPLEVEL(gtk_widget_get_toplevel (widget)),
+       not GTK_WIDGET_GET_ANCESTOR ... see 
+       http://mail.gnome.org/archives/gtk-devel-list/2001-July/msg00072.html.
+       Indicate the best practice in the docs for gtk_widget_get_toplevel().
+
+       * gtk/gtkwidget.[ch]: Expose a private _gtk_widget_hierarchy_changed(),
+       so GtkPlug can give the correct signals when transforming
+       from a child to a toplevel.
+       
+       * gtk/gtkdnd.c (gtk_drag_dest_hierarchy_changed): Handle
+       reparentation correctly.
+
+       * gtk/gtkwidget.c (gtk_widget_propagate_hierarchy_changed):
+       Propagate the previous_toplevel argument down properly.
+
+       * gtk/gtklabel.c (gtk_label_finalize): Fix unrefing
+       of wrong atr list.
+
+       * gtk/gtkplug.[ch]: Add an "embedded" signal.
+
+       * gtk/gtksocket.[ch]: Add "child_added", "child_removed"
+       signals.
+
+       * gtk/gtkplug.[ch] gtk/gtksocket.[ch]: Add 
+       functions gtk_plug_get_id(), gtk_socket_get_id(),
+       to avoid the user having to worry about realization,
+       and gdkx.h.
+
+       * tests/testsocket.c: Extend to try out the new signals
+       and gtk_plug/socket_get_id().
+
+       * gtk/gtklabel.c (gtk_label_set_pattern_internal): Fix
+       setting of underline attributes.
+
+       * gdk/x11/gdkevents-x11.c (gdk_event_translate): Ignore
+       DestroyNotify events from SubstructureNotifyMask
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_reparent):
+       Switch GDK_WINDOW_TYPE (window) as needed.
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_new): Clean up,
+       allow creation of toplevel windows as children of
+       foreign windows.
+
+       * gtk/gtkplug.c: Remove hacks involving changing private
+       fields of GdkWindow.
+
+       * gtk/gtkplug.[ch] gtk/gtksocket.c: Work to make 
+       exactly the same signals and notification
+       be emitted for local embedding as for inter-process
+       embedding.
+
 2001-07-04  James Henstridge  <james@daa.com.au>
 
        * gtk/gtkliststore.h: add missing gtk_list_store_newv prototype.
index 565f2a4075eed53b30aac18bc5a3517437545353..e4928ac7c302ac788cec64c31c4c6ff7338eb68f 100644 (file)
@@ -1,3 +1,59 @@
+Wed Jul  4 22:35:40 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtklabel.c gtk/gtkmenubar.c gtk/gtktreeviewcolumn.c
+         gtk/gtkwidget.c:
+       Check GTK_WIDGET_TOPLEVEL(gtk_widget_get_toplevel (widget)),
+       not GTK_WIDGET_GET_ANCESTOR ... see 
+       http://mail.gnome.org/archives/gtk-devel-list/2001-July/msg00072.html.
+       Indicate the best practice in the docs for gtk_widget_get_toplevel().
+
+       * gtk/gtkwidget.[ch]: Expose a private _gtk_widget_hierarchy_changed(),
+       so GtkPlug can give the correct signals when transforming
+       from a child to a toplevel.
+       
+       * gtk/gtkdnd.c (gtk_drag_dest_hierarchy_changed): Handle
+       reparentation correctly.
+
+       * gtk/gtkwidget.c (gtk_widget_propagate_hierarchy_changed):
+       Propagate the previous_toplevel argument down properly.
+
+       * gtk/gtklabel.c (gtk_label_finalize): Fix unrefing
+       of wrong atr list.
+
+       * gtk/gtkplug.[ch]: Add an "embedded" signal.
+
+       * gtk/gtksocket.[ch]: Add "child_added", "child_removed"
+       signals.
+
+       * gtk/gtkplug.[ch] gtk/gtksocket.[ch]: Add 
+       functions gtk_plug_get_id(), gtk_socket_get_id(),
+       to avoid the user having to worry about realization,
+       and gdkx.h.
+
+       * tests/testsocket.c: Extend to try out the new signals
+       and gtk_plug/socket_get_id().
+
+       * gtk/gtklabel.c (gtk_label_set_pattern_internal): Fix
+       setting of underline attributes.
+
+       * gdk/x11/gdkevents-x11.c (gdk_event_translate): Ignore
+       DestroyNotify events from SubstructureNotifyMask
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_reparent):
+       Switch GDK_WINDOW_TYPE (window) as needed.
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_new): Clean up,
+       allow creation of toplevel windows as children of
+       foreign windows.
+
+       * gtk/gtkplug.c: Remove hacks involving changing private
+       fields of GdkWindow.
+
+       * gtk/gtkplug.[ch] gtk/gtksocket.c: Work to make 
+       exactly the same signals and notification
+       be emitted for local embedding as for inter-process
+       embedding.
+
 2001-07-04  James Henstridge  <james@daa.com.au>
 
        * gtk/gtkliststore.h: add missing gtk_list_store_newv prototype.
index 565f2a4075eed53b30aac18bc5a3517437545353..e4928ac7c302ac788cec64c31c4c6ff7338eb68f 100644 (file)
@@ -1,3 +1,59 @@
+Wed Jul  4 22:35:40 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtklabel.c gtk/gtkmenubar.c gtk/gtktreeviewcolumn.c
+         gtk/gtkwidget.c:
+       Check GTK_WIDGET_TOPLEVEL(gtk_widget_get_toplevel (widget)),
+       not GTK_WIDGET_GET_ANCESTOR ... see 
+       http://mail.gnome.org/archives/gtk-devel-list/2001-July/msg00072.html.
+       Indicate the best practice in the docs for gtk_widget_get_toplevel().
+
+       * gtk/gtkwidget.[ch]: Expose a private _gtk_widget_hierarchy_changed(),
+       so GtkPlug can give the correct signals when transforming
+       from a child to a toplevel.
+       
+       * gtk/gtkdnd.c (gtk_drag_dest_hierarchy_changed): Handle
+       reparentation correctly.
+
+       * gtk/gtkwidget.c (gtk_widget_propagate_hierarchy_changed):
+       Propagate the previous_toplevel argument down properly.
+
+       * gtk/gtklabel.c (gtk_label_finalize): Fix unrefing
+       of wrong atr list.
+
+       * gtk/gtkplug.[ch]: Add an "embedded" signal.
+
+       * gtk/gtksocket.[ch]: Add "child_added", "child_removed"
+       signals.
+
+       * gtk/gtkplug.[ch] gtk/gtksocket.[ch]: Add 
+       functions gtk_plug_get_id(), gtk_socket_get_id(),
+       to avoid the user having to worry about realization,
+       and gdkx.h.
+
+       * tests/testsocket.c: Extend to try out the new signals
+       and gtk_plug/socket_get_id().
+
+       * gtk/gtklabel.c (gtk_label_set_pattern_internal): Fix
+       setting of underline attributes.
+
+       * gdk/x11/gdkevents-x11.c (gdk_event_translate): Ignore
+       DestroyNotify events from SubstructureNotifyMask
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_reparent):
+       Switch GDK_WINDOW_TYPE (window) as needed.
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_new): Clean up,
+       allow creation of toplevel windows as children of
+       foreign windows.
+
+       * gtk/gtkplug.c: Remove hacks involving changing private
+       fields of GdkWindow.
+
+       * gtk/gtkplug.[ch] gtk/gtksocket.c: Work to make 
+       exactly the same signals and notification
+       be emitted for local embedding as for inter-process
+       embedding.
+
 2001-07-04  James Henstridge  <james@daa.com.au>
 
        * gtk/gtkliststore.h: add missing gtk_list_store_newv prototype.
index 565f2a4075eed53b30aac18bc5a3517437545353..e4928ac7c302ac788cec64c31c4c6ff7338eb68f 100644 (file)
@@ -1,3 +1,59 @@
+Wed Jul  4 22:35:40 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtklabel.c gtk/gtkmenubar.c gtk/gtktreeviewcolumn.c
+         gtk/gtkwidget.c:
+       Check GTK_WIDGET_TOPLEVEL(gtk_widget_get_toplevel (widget)),
+       not GTK_WIDGET_GET_ANCESTOR ... see 
+       http://mail.gnome.org/archives/gtk-devel-list/2001-July/msg00072.html.
+       Indicate the best practice in the docs for gtk_widget_get_toplevel().
+
+       * gtk/gtkwidget.[ch]: Expose a private _gtk_widget_hierarchy_changed(),
+       so GtkPlug can give the correct signals when transforming
+       from a child to a toplevel.
+       
+       * gtk/gtkdnd.c (gtk_drag_dest_hierarchy_changed): Handle
+       reparentation correctly.
+
+       * gtk/gtkwidget.c (gtk_widget_propagate_hierarchy_changed):
+       Propagate the previous_toplevel argument down properly.
+
+       * gtk/gtklabel.c (gtk_label_finalize): Fix unrefing
+       of wrong atr list.
+
+       * gtk/gtkplug.[ch]: Add an "embedded" signal.
+
+       * gtk/gtksocket.[ch]: Add "child_added", "child_removed"
+       signals.
+
+       * gtk/gtkplug.[ch] gtk/gtksocket.[ch]: Add 
+       functions gtk_plug_get_id(), gtk_socket_get_id(),
+       to avoid the user having to worry about realization,
+       and gdkx.h.
+
+       * tests/testsocket.c: Extend to try out the new signals
+       and gtk_plug/socket_get_id().
+
+       * gtk/gtklabel.c (gtk_label_set_pattern_internal): Fix
+       setting of underline attributes.
+
+       * gdk/x11/gdkevents-x11.c (gdk_event_translate): Ignore
+       DestroyNotify events from SubstructureNotifyMask
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_reparent):
+       Switch GDK_WINDOW_TYPE (window) as needed.
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_new): Clean up,
+       allow creation of toplevel windows as children of
+       foreign windows.
+
+       * gtk/gtkplug.c: Remove hacks involving changing private
+       fields of GdkWindow.
+
+       * gtk/gtkplug.[ch] gtk/gtksocket.c: Work to make 
+       exactly the same signals and notification
+       be emitted for local embedding as for inter-process
+       embedding.
+
 2001-07-04  James Henstridge  <james@daa.com.au>
 
        * gtk/gtkliststore.h: add missing gtk_list_store_newv prototype.
index 565f2a4075eed53b30aac18bc5a3517437545353..e4928ac7c302ac788cec64c31c4c6ff7338eb68f 100644 (file)
@@ -1,3 +1,59 @@
+Wed Jul  4 22:35:40 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtklabel.c gtk/gtkmenubar.c gtk/gtktreeviewcolumn.c
+         gtk/gtkwidget.c:
+       Check GTK_WIDGET_TOPLEVEL(gtk_widget_get_toplevel (widget)),
+       not GTK_WIDGET_GET_ANCESTOR ... see 
+       http://mail.gnome.org/archives/gtk-devel-list/2001-July/msg00072.html.
+       Indicate the best practice in the docs for gtk_widget_get_toplevel().
+
+       * gtk/gtkwidget.[ch]: Expose a private _gtk_widget_hierarchy_changed(),
+       so GtkPlug can give the correct signals when transforming
+       from a child to a toplevel.
+       
+       * gtk/gtkdnd.c (gtk_drag_dest_hierarchy_changed): Handle
+       reparentation correctly.
+
+       * gtk/gtkwidget.c (gtk_widget_propagate_hierarchy_changed):
+       Propagate the previous_toplevel argument down properly.
+
+       * gtk/gtklabel.c (gtk_label_finalize): Fix unrefing
+       of wrong atr list.
+
+       * gtk/gtkplug.[ch]: Add an "embedded" signal.
+
+       * gtk/gtksocket.[ch]: Add "child_added", "child_removed"
+       signals.
+
+       * gtk/gtkplug.[ch] gtk/gtksocket.[ch]: Add 
+       functions gtk_plug_get_id(), gtk_socket_get_id(),
+       to avoid the user having to worry about realization,
+       and gdkx.h.
+
+       * tests/testsocket.c: Extend to try out the new signals
+       and gtk_plug/socket_get_id().
+
+       * gtk/gtklabel.c (gtk_label_set_pattern_internal): Fix
+       setting of underline attributes.
+
+       * gdk/x11/gdkevents-x11.c (gdk_event_translate): Ignore
+       DestroyNotify events from SubstructureNotifyMask
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_reparent):
+       Switch GDK_WINDOW_TYPE (window) as needed.
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_new): Clean up,
+       allow creation of toplevel windows as children of
+       foreign windows.
+
+       * gtk/gtkplug.c: Remove hacks involving changing private
+       fields of GdkWindow.
+
+       * gtk/gtkplug.[ch] gtk/gtksocket.c: Work to make 
+       exactly the same signals and notification
+       be emitted for local embedding as for inter-process
+       embedding.
+
 2001-07-04  James Henstridge  <james@daa.com.au>
 
        * gtk/gtkliststore.h: add missing gtk_list_store_newv prototype.
index 565f2a4075eed53b30aac18bc5a3517437545353..e4928ac7c302ac788cec64c31c4c6ff7338eb68f 100644 (file)
@@ -1,3 +1,59 @@
+Wed Jul  4 22:35:40 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtklabel.c gtk/gtkmenubar.c gtk/gtktreeviewcolumn.c
+         gtk/gtkwidget.c:
+       Check GTK_WIDGET_TOPLEVEL(gtk_widget_get_toplevel (widget)),
+       not GTK_WIDGET_GET_ANCESTOR ... see 
+       http://mail.gnome.org/archives/gtk-devel-list/2001-July/msg00072.html.
+       Indicate the best practice in the docs for gtk_widget_get_toplevel().
+
+       * gtk/gtkwidget.[ch]: Expose a private _gtk_widget_hierarchy_changed(),
+       so GtkPlug can give the correct signals when transforming
+       from a child to a toplevel.
+       
+       * gtk/gtkdnd.c (gtk_drag_dest_hierarchy_changed): Handle
+       reparentation correctly.
+
+       * gtk/gtkwidget.c (gtk_widget_propagate_hierarchy_changed):
+       Propagate the previous_toplevel argument down properly.
+
+       * gtk/gtklabel.c (gtk_label_finalize): Fix unrefing
+       of wrong atr list.
+
+       * gtk/gtkplug.[ch]: Add an "embedded" signal.
+
+       * gtk/gtksocket.[ch]: Add "child_added", "child_removed"
+       signals.
+
+       * gtk/gtkplug.[ch] gtk/gtksocket.[ch]: Add 
+       functions gtk_plug_get_id(), gtk_socket_get_id(),
+       to avoid the user having to worry about realization,
+       and gdkx.h.
+
+       * tests/testsocket.c: Extend to try out the new signals
+       and gtk_plug/socket_get_id().
+
+       * gtk/gtklabel.c (gtk_label_set_pattern_internal): Fix
+       setting of underline attributes.
+
+       * gdk/x11/gdkevents-x11.c (gdk_event_translate): Ignore
+       DestroyNotify events from SubstructureNotifyMask
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_reparent):
+       Switch GDK_WINDOW_TYPE (window) as needed.
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_new): Clean up,
+       allow creation of toplevel windows as children of
+       foreign windows.
+
+       * gtk/gtkplug.c: Remove hacks involving changing private
+       fields of GdkWindow.
+
+       * gtk/gtkplug.[ch] gtk/gtksocket.c: Work to make 
+       exactly the same signals and notification
+       be emitted for local embedding as for inter-process
+       embedding.
+
 2001-07-04  James Henstridge  <james@daa.com.au>
 
        * gtk/gtkliststore.h: add missing gtk_list_store_newv prototype.
index a2c7740b7173ae2a1db10d51824a61b650f47052..5ca9d91952570c433a93d04aec44edbe0db16370 100644 (file)
@@ -1216,14 +1216,20 @@ gdk_event_translate (GdkEvent *event,
       GDK_NOTE (EVENTS,
                g_message ("destroy notify:\twindow: %ld",
                           xevent->xdestroywindow.window));
-      
-      event->any.type = GDK_DESTROY;
-      event->any.window = window;
-      
-      return_val = window_private && !GDK_WINDOW_DESTROYED (window);
-      
-      if (window && GDK_WINDOW_XID (window) != GDK_ROOT_WINDOW())
-       gdk_window_destroy_notify (window);
+
+      /* Ignore DestroyNotify from SubstructureNotifyMask */
+      if (xevent->xdestroywindow.window == xevent->xdestroywindow.event)
+       {
+         event->any.type = GDK_DESTROY;
+         event->any.window = window;
+         
+         return_val = window_private && !GDK_WINDOW_DESTROYED (window);
+         
+         if (window && GDK_WINDOW_XID (window) != GDK_ROOT_WINDOW())
+           gdk_window_destroy_notify (window);
+       }
+      else
+       return_val = FALSE;
       break;
       
     case UnmapNotify:
index 412476995294401875a769f7af8845ef27ede71f..9f8aebaa98ee430bfe2cf8f6b02f06c974067dc7 100644 (file)
@@ -403,6 +403,26 @@ gdk_window_new (GdkWindow     *parent,
       xattributes_mask |= CWWinGravity;
     }
   
+  /* Sanity checks */
+  switch (private->window_type)
+    {
+    case GDK_WINDOW_TOPLEVEL:
+    case GDK_WINDOW_DIALOG:
+    case GDK_WINDOW_TEMP:
+      if (GDK_WINDOW_TYPE (parent) != GDK_WINDOW_ROOT &&
+         GDK_WINDOW_TYPE (parent) != GDK_WINDOW_FOREIGN)
+       {
+         g_warning (G_STRLOC "Toplevel windows must be created as children of\n"
+                    "of a window of type GDK_WINDOW_ROOT or GDK_WINDOW_FOREIGN");
+         xparent = gdk_root_window;
+       }
+    case GDK_WINDOW_CHILD:
+      break;
+    default:
+      g_warning (G_STRLOC "cannot make windows of type %d", private->window_type);
+      return NULL;
+    }
+         
   if (attributes->wclass == GDK_INPUT_OUTPUT)
     {
       class = InputOutput;
@@ -445,42 +465,16 @@ gdk_window_new (GdkWindow     *parent,
        xattributes.bit_gravity = NorthWestGravity;
       
       xattributes_mask |= CWBitGravity;
-  
-      switch (private->window_type)
+
+      xattributes.colormap = GDK_COLORMAP_XCOLORMAP (draw_impl->colormap);
+      xattributes_mask |= CWColormap;
+
+      if (private->window_type == GDK_WINDOW_TEMP)
        {
-       case GDK_WINDOW_TOPLEVEL:
-         xattributes.colormap = GDK_COLORMAP_XCOLORMAP (draw_impl->colormap);
-         xattributes_mask |= CWColormap;
-         
-         xparent = gdk_root_window;
-         break;
-         
-       case GDK_WINDOW_CHILD:
-         xattributes.colormap = GDK_COLORMAP_XCOLORMAP (draw_impl->colormap);
-         xattributes_mask |= CWColormap;
-         break;
-         
-       case GDK_WINDOW_DIALOG:
-         xattributes.colormap = GDK_COLORMAP_XCOLORMAP (draw_impl->colormap);
-         xattributes_mask |= CWColormap;
-         
-         xparent = gdk_root_window;
-         break;
-         
-       case GDK_WINDOW_TEMP:
-         xattributes.colormap = GDK_COLORMAP_XCOLORMAP (draw_impl->colormap);
-         xattributes_mask |= CWColormap;
-         
-         xparent = gdk_root_window;
-         
          xattributes.save_under = True;
          xattributes.override_redirect = True;
          xattributes.cursor = None;
          xattributes_mask |= CWSaveUnder | CWOverrideRedirect;
-         break;
-       case GDK_WINDOW_ROOT:
-         g_error ("cannot make windows of type GDK_WINDOW_ROOT");
-         break;
        }
     }
   else
@@ -1040,6 +1034,7 @@ gdk_window_reparent (GdkWindow *window,
   g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
   g_return_if_fail (new_parent == NULL || GDK_IS_WINDOW (new_parent));
+  g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_ROOT);
   
   if (!new_parent)
     new_parent = gdk_parent_root;
@@ -1055,7 +1050,37 @@ gdk_window_reparent (GdkWindow *window,
                     x, y);
   
   window_private->parent = (GdkWindowObject *)new_parent;
-  
+
+  /* Switch the window type as appropriate */
+
+  switch (GDK_WINDOW_TYPE (new_parent))
+    {
+    case GDK_WINDOW_ROOT:
+    case GDK_WINDOW_FOREIGN:
+      /* Now a toplevel */
+      if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
+       {
+         GDK_WINDOW_TYPE (window) = GDK_WINDOW_TOPLEVEL;
+         XSetWMProtocols (GDK_WINDOW_XDISPLAY (window),
+                          GDK_WINDOW_XID (window),
+                          gdk_wm_window_protocols, 3);
+       }
+    case GDK_WINDOW_TOPLEVEL:
+    case GDK_WINDOW_CHILD:
+    case GDK_WINDOW_DIALOG:
+    case GDK_WINDOW_TEMP:
+      if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD &&
+         GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
+       {
+         /* If we were being sophisticated, we'd save the old window type
+          * here, and restore it if we were reparented back to the
+          * toplevel. However, the difference between different types
+          * of toplevels only really matters on creation anyways.
+          */
+         GDK_WINDOW_TYPE (window) = GDK_WINDOW_CHILD;
+       }
+    }
+
   if (old_parent_private)
     old_parent_private->children = g_list_remove (old_parent_private->children, window);
   
index bff1b76b45a5ea278ff70eb00825fb14ba35c58e..f97ad54d3e514ada8b2847053087c9c462653519 100644 (file)
@@ -197,30 +197,32 @@ static gboolean      gtk_drag_highlight_expose   (GtkWidget      *widget,
                                                  GdkEventExpose *event,
                                                  gpointer        data);
 
-static void     gtk_drag_selection_received (GtkWidget        *widget,
-                                            GtkSelectionData *selection_data,
-                                            guint32           time,
-                                            gpointer          data);
-static void     gtk_drag_find_widget        (GtkWidget        *widget,
-                                            GtkDragFindData  *data);
-static void     gtk_drag_proxy_begin        (GtkWidget        *widget,
-                                            GtkDragDestInfo  *dest_info,
-                                            guint32           time);
-static void     gtk_drag_dest_realized      (GtkWidget        *widget);
-static void     gtk_drag_dest_site_destroy  (gpointer          data);
-static void     gtk_drag_dest_leave         (GtkWidget        *widget,
-                                            GdkDragContext   *context,
-                                            guint             time);
-static gboolean gtk_drag_dest_motion        (GtkWidget        *widget,
-                                            GdkDragContext   *context,
-                                            gint              x,
-                                            gint              y,
-                                            guint             time);
-static gboolean gtk_drag_dest_drop          (GtkWidget        *widget,
-                                            GdkDragContext   *context,
-                                            gint              x,
-                                            gint              y,
-                                            guint             time);
+static void     gtk_drag_selection_received     (GtkWidget        *widget,
+                                                GtkSelectionData *selection_data,
+                                                guint32           time,
+                                                gpointer          data);
+static void     gtk_drag_find_widget            (GtkWidget        *widget,
+                                                GtkDragFindData  *data);
+static void     gtk_drag_proxy_begin            (GtkWidget        *widget,
+                                                GtkDragDestInfo  *dest_info,
+                                                guint32           time);
+static void     gtk_drag_dest_realized          (GtkWidget        *widget);
+static void     gtk_drag_dest_hierarchy_changed (GtkWidget        *widget,
+                                                GtkWidget        *old_toplevel);
+static void     gtk_drag_dest_site_destroy      (gpointer          data);
+static void     gtk_drag_dest_leave             (GtkWidget        *widget,
+                                                GdkDragContext   *context,
+                                                guint             time);
+static gboolean gtk_drag_dest_motion            (GtkWidget        *widget,
+                                                GdkDragContext   *context,
+                                                gint              x,
+                                                gint              y,
+                                                guint             time);
+static gboolean gtk_drag_dest_drop              (GtkWidget        *widget,
+                                                GdkDragContext   *context,
+                                                gint              x,
+                                                gint              y,
+                                                guint             time);
 
 static GtkDragDestInfo *  gtk_drag_get_dest_info     (GdkDragContext *context,
                                                      gboolean        create);
@@ -812,6 +814,8 @@ gtk_drag_dest_set_internal (GtkWidget       *widget,
 
   gtk_signal_connect (GTK_OBJECT (widget), "realize",
                      GTK_SIGNAL_FUNC (gtk_drag_dest_realized), site);
+  gtk_signal_connect (GTK_OBJECT (widget), "hierarchy_changed",
+                     GTK_SIGNAL_FUNC (gtk_drag_dest_hierarchy_changed), site);
 
   gtk_object_set_data_full (GTK_OBJECT (widget), "gtk-drag-dest",
                            site, gtk_drag_dest_site_destroy);
@@ -1428,7 +1432,18 @@ static void
 gtk_drag_dest_realized (GtkWidget *widget)
 {
   GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
-  gdk_window_register_dnd (toplevel->window);
+
+  if (GTK_WIDGET_TOPLEVEL (toplevel))
+    gdk_window_register_dnd (toplevel->window);
+}
+
+static void
+gtk_drag_dest_hierarchy_changed (GtkWidget *widget)
+{
+  GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
+
+  if (GTK_WIDGET_TOPLEVEL (toplevel) && GTK_WIDGET_REALIZED (toplevel))
+    gdk_window_register_dnd (toplevel->window);
 }
 
 static void
index 58c910c9610867f2cae32b2497f243016d00a2b7..c240144bb2736f0f719404c5a8c3e6c67dd42cad 100644 (file)
@@ -2030,7 +2030,7 @@ gtk_entry_real_activate (GtkEntry *entry)
   if (entry->activates_default)
     {
       toplevel = gtk_widget_get_toplevel (widget);
-      if (toplevel && GTK_IS_WINDOW (toplevel))
+      if (GTK_IS_WINDOW (toplevel))
        {
          window = GTK_WINDOW (toplevel);
       
index 64f85330edbce50b5d5f3752a93d527ffe56ac35..db4c7e8ef54ec85e620def867390932ce48c7482 100644 (file)
@@ -492,8 +492,7 @@ gtk_label_setup_mnemonic (GtkLabel *label,
     return;
   
   toplevel = gtk_widget_get_toplevel (GTK_WIDGET (label));
-  
-  if (GTK_IS_WINDOW (toplevel))
+  if (GTK_WIDGET_TOPLEVEL (toplevel))
     {
       gtk_window_add_mnemonic (GTK_WINDOW (toplevel),
                               label->mnemonic_keyval,
@@ -953,7 +952,10 @@ gtk_label_set_pattern_internal (GtkLabel    *label,
   g_return_if_fail (GTK_IS_LABEL (label));
   
   attrs = gtk_label_pattern_to_attrs (label, pattern);
-  gtk_label_set_attributes_internal (label, attrs);
+
+  if (label->effective_attrs)
+    pango_attr_list_unref (label->effective_attrs);
+  label->effective_attrs = attrs;
 }
 
 void
@@ -1092,7 +1094,7 @@ gtk_label_finalize (GObject *object)
     pango_attr_list_unref (label->attrs);
 
   if (label->effective_attrs)
-    pango_attr_list_unref (label->attrs);
+    pango_attr_list_unref (label->effective_attrs);
 
   g_free (label->select_info);
 
index 29824189283081bb11c2997814057e77a03c071e..d17952e953390527b2a5720b905e55da7812065d 100644 (file)
@@ -483,10 +483,10 @@ gtk_menu_bar_hierarchy_changed (GtkWidget *widget,
 
   toplevel = gtk_widget_get_toplevel (widget);
 
-  if (old_toplevel && GTK_IS_WINDOW (old_toplevel))
+  if (old_toplevel)
     remove_from_window (old_toplevel, menubar);
   
-  if (toplevel && GTK_IS_WINDOW (toplevel))
+  if (GTK_WIDGET_TOPLEVEL (toplevel))
     add_to_window (GTK_WINDOW (toplevel), menubar);
 }
 
index 03d7e22f069ef4650a234144740eb6b4f6bd0df3..743a74090d402e71079c3294f3a2b65553d6a7e8 100644 (file)
@@ -26,6 +26,7 @@
  */
 
 #include "gtkmain.h"
+#include "gtkmarshal.h"
 #include "gtkplug.h"
 #include "gtkprivate.h"
 
@@ -75,6 +76,13 @@ static void xembed_set_info            (GdkWindow     *window,
 static GtkWindowClass *parent_class = NULL;
 static GtkBinClass *bin_class = NULL;
 
+enum {
+  EMBEDDED,
+  LAST_SIGNAL
+}; 
+
+static guint plug_signals[LAST_SIGNAL] = { 0 };
+
 GtkType
 gtk_plug_get_type ()
 {
@@ -129,6 +137,15 @@ gtk_plug_class_init (GtkPlugClass *class)
 #if 0  
   window_class->accel_entries_changed = gtk_plug_accel_entries_changed;
 #endif
+
+  plug_signals[EMBEDDED] =
+    g_signal_new ("embedded",
+                 G_OBJECT_CLASS_TYPE (class),
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET (GtkPlugClass, embedded),
+                 NULL, NULL,
+                 gtk_marshal_VOID__VOID,
+                 GTK_TYPE_NONE, 0);
 }
 
 static void
@@ -146,11 +163,34 @@ static void
 gtk_plug_set_is_child (GtkPlug  *plug,
                       gboolean  is_child)
 {
+  g_assert (!GTK_WIDGET (plug)->parent);
+      
   if (is_child)
     {
+      if (plug->modality_window)
+       handle_modality_off (plug);
+
+      if (plug->modality_group)
+       {
+         gtk_window_group_remove_window (plug->modality_group, GTK_WINDOW (plug));
+         g_object_unref (plug->modality_group);
+         plug->modality_group = NULL;
+       }
+      
       GTK_WIDGET_UNSET_FLAGS (plug, GTK_TOPLEVEL);
-      GTK_PRIVATE_UNSET_FLAG (plug, GTK_ANCHORED);
       gtk_container_set_resize_mode (GTK_CONTAINER (plug), GTK_RESIZE_PARENT);
+
+      _gtk_widget_propagate_hierarchy_changed (GTK_WIDGET (plug), GTK_WIDGET (plug));
+    }
+  else
+    {
+      plug->modality_group = gtk_window_group_new ();
+      gtk_window_group_add_window (plug->modality_group, GTK_WINDOW (plug));
+      
+      GTK_WIDGET_SET_FLAGS (plug, GTK_TOPLEVEL);
+      gtk_container_set_resize_mode (GTK_CONTAINER (plug), GTK_RESIZE_QUEUE);
+
+      _gtk_widget_propagate_hierarchy_changed (GTK_WIDGET (plug), NULL);
     }
 }
 
@@ -165,12 +205,14 @@ void
 _gtk_plug_add_to_socket (GtkPlug   *plug,
                         GtkSocket *socket)
 {
-  GtkWidget *widget = GTK_WIDGET (plug);
+  GtkWidget *widget;
   
   g_return_if_fail (GTK_IS_PLUG (plug));
   g_return_if_fail (GTK_IS_SOCKET (socket));
   g_return_if_fail (GTK_WIDGET_REALIZED (socket));
 
+  widget = GTK_WIDGET (plug);
+
   gtk_plug_set_is_child (plug, TRUE);
   plug->same_app = TRUE;
   socket->plug_widget = widget;
@@ -189,6 +231,71 @@ _gtk_plug_add_to_socket (GtkPlug   *plug,
 
       gtk_widget_queue_resize (widget);
     }
+
+  g_signal_emit_by_name (G_OBJECT (socket), "plug_added", 0);
+}
+
+/**
+ * _gtk_plug_add_to_socket:
+ * @plug: a #GtkPlug
+ * @socket: a #GtkSocket
+ * 
+ * Remove a plug from a socket within the same application.
+ **/
+void
+_gtk_plug_remove_from_socket (GtkPlug   *plug,
+                             GtkSocket *socket)
+{
+  GtkWidget *widget;
+  GdkEvent event;
+  gboolean result;
+  gboolean widget_was_visible;
+
+  g_return_if_fail (GTK_IS_PLUG (plug));
+  g_return_if_fail (GTK_IS_SOCKET (socket));
+  g_return_if_fail (GTK_WIDGET_REALIZED (plug));
+
+  widget = GTK_WIDGET (plug);
+
+  g_object_ref (plug);
+  g_object_ref (socket);
+
+  widget_was_visible = GTK_WIDGET_VISIBLE (plug);
+  
+  gdk_window_hide (widget->window);
+  gdk_window_reparent (widget->window, GDK_ROOT_PARENT (), 0, 0);
+
+  GTK_PRIVATE_SET_FLAG (plug, GTK_IN_REPARENT);
+  gtk_widget_unparent (GTK_WIDGET (plug));
+  GTK_PRIVATE_UNSET_FLAG (plug, GTK_IN_REPARENT);
+  
+  socket->plug_widget = NULL;
+  socket->plug_window = NULL;
+  socket->same_app = FALSE;
+
+  plug->same_app = FALSE;
+  plug->socket_window = FALSE;
+
+  gtk_plug_set_is_child (plug, FALSE);
+                   
+  g_signal_emit_by_name (G_OBJECT (socket), "plug_removed", &result);
+  if (!result)
+    gtk_widget_destroy (GTK_WIDGET (socket));
+
+  event.any.type = GDK_DELETE;
+  event.any.window = g_object_ref (widget->window);
+  event.any.send_event = FALSE;
+  
+  if (!gtk_widget_event (widget, &event))
+    gtk_widget_destroy (widget);
+  
+  g_object_unref (event.any.window);
+  g_object_unref (plug);
+
+  if (widget_was_visible && GTK_WIDGET_VISIBLE (socket))
+    gtk_widget_queue_resize (GTK_WIDGET (socket));
+
+  g_object_unref (socket);
 }
 
 void
@@ -216,6 +323,9 @@ gtk_plug_construct (GtkPlug         *plug,
              plug->socket_window = NULL;
            }
        }
+
+      if (plug->socket_window)
+       g_signal_emit (G_OBJECT (plug), plug_signals[EMBEDDED], 0);
     }
 }
 
@@ -229,6 +339,27 @@ gtk_plug_new (GdkNativeWindow socket_id)
   return GTK_WIDGET (plug);
 }
 
+/**
+ * gtk_plug_get_id:
+ * @plug: a #GtkPlug.
+ * 
+ * Gets the window ID of a #GtkPlug widget, which can then
+ * be used to embed this window inside another window, for
+ * instance with gtk_sock_add_id (id).
+ * 
+ * Return value: the window ID for the plug
+ **/
+GdkNativeWindow
+gtk_plug_get_id (GtkPlug *plug)
+{
+  g_return_val_if_fail (GTK_IS_PLUG (plug), 0);
+
+  if (!GTK_WIDGET_REALIZED (plug))
+    gtk_widget_realize (GTK_WIDGET (plug));
+
+  return GDK_WINDOW_XWINDOW (GTK_WIDGET (plug)->window);
+}
+
 static void
 gtk_plug_unrealize (GtkWidget *widget)
 {
@@ -300,6 +431,8 @@ gtk_plug_realize (GtkWidget *widget)
 
   if (GTK_WIDGET_TOPLEVEL (widget))
     {
+      attributes.window_type = GDK_WINDOW_TOPLEVEL;
+
       gdk_error_trap_push ();
       widget->window = gdk_window_new (plug->socket_window, 
                                       &attributes, attributes_mask);
@@ -312,8 +445,7 @@ gtk_plug_realize (GtkWidget *widget)
          gdk_error_trap_pop ();
          widget->window = gdk_window_new (NULL, &attributes, attributes_mask);
        }
-
-      GDK_WINDOW_TYPE (widget->window) = GDK_WINDOW_TOPLEVEL;
+      
       gdk_window_add_filter (widget->window, gtk_plug_filter_func, widget);
 
       plug->modality_group = gtk_window_group_new ();
@@ -904,9 +1036,106 @@ gtk_plug_filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
                                 xevent->xclient.data.l[0]);
                                 
 
+         return GDK_FILTER_REMOVE;
+       }
+      else if (xevent->xclient.message_type == gdk_atom_intern ("WM_DELETE_WINDOW", FALSE))
+       {
+         /* We filter these out because we take being reparented back to the
+          * root window as the reliable end of the embedding protocol
+          */
+
          return GDK_FILTER_REMOVE;
        }
       break;
+    case ReparentNotify:
+      {
+       XReparentEvent *xre = &xevent->xreparent;
+       gboolean was_embedded = plug->socket_window != NULL;
+
+       return_val = GDK_FILTER_REMOVE;
+       
+       g_object_ref (plug);
+       
+       if (was_embedded)
+         {
+           /* End of embedding protocol for previous socket */
+           
+           /* FIXME: race if we remove from another socket and
+            * then add to a local window before we get notification
+            * Probably need check in _gtk_plug_add_to_socket
+            */
+           
+           if (xre->parent != GDK_WINDOW_XWINDOW (plug->socket_window))
+             {
+               GtkWidget *widget = GTK_WIDGET (plug);
+
+               gdk_window_set_user_data (plug->socket_window, NULL);
+               gdk_window_unref (plug->socket_window);
+               plug->socket_window = NULL;
+
+               /* Emit a delete window, as if the user attempted
+                * to close the toplevel. Simple as to how we
+                * handle WM_DELETE_WINDOW, if it isn't handled
+                * we destroy the widget. BUt only do this if
+                * we are being reparented to the root window.
+                * Moving from one embedder to another should
+                * be invisible to the app.
+                */
+
+               if (xre->parent == GDK_ROOT_WINDOW())
+                 {
+                   GdkEvent event;
+                   
+                   event.any.type = GDK_DELETE;
+                   event.any.window = g_object_ref (widget->window);
+                   event.any.send_event = FALSE;
+                   
+                   if (!gtk_widget_event (widget, &event))
+                     gtk_widget_destroy (widget);
+                   
+                   g_object_unref (event.any.window);
+                 }
+             }
+           else
+             break;
+         }
+
+       if (xre->parent != GDK_ROOT_WINDOW ())
+         {
+           /* Start of embedding protocol */
+
+           plug->socket_window = gdk_window_lookup (xre->parent);
+           if (plug->socket_window)
+             {
+               gpointer user_data = NULL;
+               gdk_window_get_user_data (plug->socket_window, &user_data);
+
+               if (user_data)
+                 {
+                   g_warning (G_STRLOC "Plug reparented unexpectedly into window in the same process");
+                   plug->socket_window = NULL;
+                   break;
+                 }
+
+               g_object_ref (plug->socket_window);
+             }
+           else
+             {
+               plug->socket_window = gdk_window_foreign_new (xre->parent);
+               if (!plug->socket_window) /* Already gone */
+                 break;
+             }
+
+           /* FIXME: Add grabbed keys here */
+
+           if (!was_embedded)
+             g_signal_emit (G_OBJECT (plug), plug_signals[EMBEDDED], 0);
+         }
+       
+       g_object_unref (plug);
+       
+       break;
+      }
     }
 
   return GDK_FILTER_CONTINUE;
index d3274c50b497a84d3c49d986b3464219d1af63a3..4c568e817d8e38d8d8b1625fe7620ba5b560feea 100644 (file)
@@ -62,16 +62,21 @@ struct _GtkPlug
 struct _GtkPlugClass
 {
   GtkWindowClass parent_class;
+
+  void (*embedded) (GtkPlug *plug);
 };
 
 
 GtkType    gtk_plug_get_type  (void) G_GNUC_CONST;
 void       gtk_plug_construct (GtkPlug *plug, GdkNativeWindow socket_id);
-GtkWidget* gtk_plug_new       (GdkNativeWindow socket_id);
 
+GtkWidget*      gtk_plug_new    (GdkNativeWindow  socket_id);
+GdkNativeWindow gtk_plug_get_id (GtkPlug         *plug);
 
-void _gtk_plug_add_to_socket (GtkPlug   *plug,
-                             GtkSocket *socket);
+void _gtk_plug_add_to_socket      (GtkPlug   *plug,
+                                  GtkSocket *socket);
+void _gtk_plug_remove_from_socket (GtkPlug   *plug,
+                                  GtkSocket *socket);
 
 #ifdef __cplusplus
 }
index a8e76850b18ed072d63b5e1d4c7e5471b680d707..70e2fb7d377cd0b87cfef079cb6a9a0dde8fa516 100644 (file)
 
 #include "gdk/gdkkeysyms.h"
 #include "gtkmain.h"
+#include "gtkmarshal.h"
 #include "gtkwindow.h"
 #include "gtkplug.h"
+#include "gtkprivate.h"
 #include "gtksignal.h"
 #include "gtksocket.h"
 #include "gtkdnd.h"
@@ -91,6 +93,14 @@ static gboolean xembed_get_info     (GdkWindow     *gdk_window,
 
 /* Local data */
 
+enum {
+  PLUG_ADDED,
+  PLUG_REMOVED,
+  LAST_SIGNAL
+}; 
+
+static guint socket_signals[LAST_SIGNAL] = { 0 };
+
 static GtkWidgetClass *parent_class = NULL;
 
 GtkType
@@ -143,6 +153,23 @@ gtk_socket_class_init (GtkSocketClass *class)
   
   container_class->remove = gtk_socket_remove;
   container_class->forall = gtk_socket_forall;
+
+  socket_signals[PLUG_ADDED] =
+    g_signal_new ("plug_added",
+                 G_OBJECT_CLASS_TYPE (class),
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET (GtkSocketClass, plug_added),
+                 NULL, NULL,
+                 gtk_marshal_VOID__VOID,
+                 GTK_TYPE_NONE, 0);
+  socket_signals[PLUG_REMOVED] =
+    g_signal_new ("plug_removed",
+                 G_OBJECT_CLASS_TYPE (class),
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET (GtkSocketClass, plug_removed),
+                  _gtk_boolean_handled_accumulator, NULL,
+                 gtk_marshal_BOOLEAN__VOID,
+                 G_TYPE_BOOLEAN, 0);
 }
 
 static void
@@ -160,6 +187,14 @@ gtk_socket_init (GtkSocket *socket)
   socket->need_map = FALSE;
 }
 
+/**
+ * gtk_socket_new:
+ * @void: 
+ * 
+ * Create a new empty #GtkSocket.
+ * 
+ * Return value:  the new #GtkSocket.
+ **/
 GtkWidget*
 gtk_socket_new (void)
 {
@@ -170,12 +205,85 @@ gtk_socket_new (void)
   return GTK_WIDGET (socket);
 }
 
+/**
+ * gtk_socket_steal:
+ * @socket: a #GtkSocket
+ * @id: the XID of an existing toplevel window.
+ * 
+ * Reparents a pre-existing toplevel window into a #GtkSocket. This is
+ * meant to embed clients that do not know about embedding into a
+ * #GtkSocket, however doing so is inherently unreliable, and using
+ * this function is not recommended.
+ *
+ * The #GtkSocket must have already be added into a toplevel window
+ *  before you can make this call.
+ **/
 void           
 gtk_socket_steal (GtkSocket *socket, GdkNativeWindow id)
 {
+  g_return_if_fail (GTK_IS_SOCKET (socket));
+  g_return_if_fail (GTK_WIDGET_ANCHORED (socket));
+
+  if (!GTK_WIDGET_REALIZED (socket))
+    gtk_widget_realize (GTK_WIDGET (socket));
+
   gtk_socket_add_window (socket, id, TRUE);
 }
 
+/**
+ * gtk_socket_add_id:
+ * @socket: a #GtkSocket
+ * @id: the XID of a client participating in the XEMBED protocol.
+ *
+ * Adds an XEMBED client, such as a #GtkPlug, to the #GtkSocket.  The
+ * client may be in the same process or in a different process. 
+ * 
+ * To embed a #GtkPlug in a #GtkSocket, you can either create the
+ * #GtkPlug with gtk_plug_new (0), call gtk_plug_get_id() to get the
+ * window ID of the plug, and then pass that to the
+ * gtk_socket_add_id(), or you can call gtk_socket_get_id() to get the
+ * window ID for the socket, and call gtk_plug_new() passing in that
+ * ID.
+ *
+ * The #GtkSocket must have already be added into a toplevel window
+ *  before you can make this call.
+ **/
+void           
+gtk_socket_add_id (GtkSocket *socket, GdkNativeWindow id)
+{
+  g_return_if_fail (GTK_IS_SOCKET (socket));
+  g_return_if_fail (GTK_WIDGET_ANCHORED (socket));
+
+  if (!GTK_WIDGET_REALIZED (socket))
+    gtk_widget_realize (GTK_WIDGET (socket));
+
+  gtk_socket_add_window (socket, id, TRUE);
+}
+
+/**
+ * gtk_socket_get_id:
+ * @socket: a #GtkSocket.
+ * 
+ * Gets the window ID of a #GtkSocket widget, which can then
+ * be used to create a client embedded inside the socket, for
+ * instance with gtk_socket_new (id). The #GtkSocket must
+ * have already be added into a toplevel window before you
+ * can make this call.
+ * 
+ * Return value: the window ID for the socket
+ **/
+GdkNativeWindow
+gtk_socket_get_id (GtkSocket *socket)
+{
+  g_return_val_if_fail (GTK_IS_SOCKET (socket), 0);
+  g_return_val_if_fail (GTK_WIDGET_ANCHORED (socket), 0);
+
+  if (!GTK_WIDGET_REALIZED (socket))
+    gtk_widget_realize (GTK_WIDGET (socket));
+
+  return GDK_WINDOW_XWINDOW (GTK_WIDGET (socket)->window);
+}
+
 static void
 gtk_socket_realize (GtkWidget *widget)
 {
@@ -232,20 +340,20 @@ gtk_socket_realize (GtkWidget *widget)
 static void
 gtk_socket_unrealize (GtkWidget *widget)
 {
-  GtkSocket *socket;
-
-  g_return_if_fail (widget != NULL);
-  g_return_if_fail (GTK_IS_SOCKET (widget));
-
-  socket = GTK_SOCKET (widget);
+  GtkSocket *socket = GTK_SOCKET (widget);
 
-  if (socket->plug_window)
+  if (socket->plug_widget)
+    {
+      _gtk_plug_remove_from_socket (GTK_PLUG (socket->plug_widget), socket);
+    }
+  else if (socket->plug_window)
     {
       GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (socket));
       if (toplevel && GTK_IS_WINDOW (toplevel))
        gtk_window_remove_embedded_xid (GTK_WINDOW (toplevel), 
                                        GDK_WINDOW_XWINDOW (socket->plug_window));
 
+      g_object_unref (socket->plug_window);
       socket->plug_window = NULL;
     }
 
@@ -266,13 +374,7 @@ static void
 gtk_socket_size_request (GtkWidget      *widget,
                         GtkRequisition *requisition)
 {
-  GtkSocket *socket;
-
-  g_return_if_fail (widget != NULL);
-  g_return_if_fail (GTK_IS_SOCKET (widget));
-  g_return_if_fail (requisition != NULL);
-  
-  socket = GTK_SOCKET (widget);
+  GtkSocket *socket = GTK_SOCKET (widget);
 
   if (socket->plug_widget)
     {
@@ -800,20 +902,10 @@ gtk_socket_remove (GtkContainer *container,
                   GtkWidget    *child)
 {
   GtkSocket *socket = GTK_SOCKET (container);
-  gboolean widget_was_visible;
 
   g_return_if_fail (child == socket->plug_widget);
 
-  widget_was_visible = GTK_WIDGET_VISIBLE (child);
-  
-  gtk_widget_unparent (child);
-  socket->plug_widget = NULL;
-  
-  /* queue resize regardless of GTK_WIDGET_VISIBLE (container),
-   * since that's what is needed by toplevels, which derive from GtkBin.
-   */
-  if (widget_was_visible)
-    gtk_widget_queue_resize (GTK_WIDGET (container));
+  _gtk_plug_remove_from_socket (GTK_PLUG (socket->plug_widget), socket);
 }
 
 static void
@@ -965,6 +1057,9 @@ gtk_socket_add_window (GtkSocket        *socket,
 
       gtk_widget_queue_resize (GTK_WIDGET (socket));
     }
+
+  if (socket->plug_window)
+    g_signal_emit (G_OBJECT (socket), socket_signals[PLUG_ADDED], 0);
 }
 
 
@@ -1171,26 +1266,20 @@ gtk_socket_filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
        XCreateWindowEvent *xcwe = &xevent->xcreatewindow;
 
        if (!socket->plug_window)
-         gtk_socket_add_window (socket, xcwe->window, FALSE);
-
-       if (socket->plug_window)
          {
-           gdk_error_trap_push ();
-           gdk_window_move_resize(socket->plug_window,
-                                  0, 0,
-                                  widget->allocation.width, 
-                                  widget->allocation.height);
-           gdk_flush ();
-           gdk_error_trap_pop ();
-       
-           socket->request_width = xcwe->width;
-           socket->request_height = xcwe->height;
-           socket->have_size = TRUE;
+           gtk_socket_add_window (socket, xcwe->window, FALSE);
 
-           GTK_NOTE(PLUGSOCKET,
-                    g_message ("GtkSocket - window created with size: %d %d",
-                               socket->request_width,
-                               socket->request_height));
+           if (socket->plug_window)
+             {
+               socket->request_width = xcwe->width;
+               socket->request_height = xcwe->height;
+               socket->have_size = TRUE;
+               
+               GTK_NOTE(PLUGSOCKET,
+                        g_message ("GtkSocket - window created with size: %d %d",
+                                   socket->request_width,
+                                   socket->request_height));
+             }
          }
        
        return_val = GDK_FILTER_REMOVE;
@@ -1235,10 +1324,14 @@ gtk_socket_filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
       {
        XDestroyWindowEvent *xdwe = &xevent->xdestroywindow;
 
+       /* Note that we get destroy notifies both from SubstructureNotify on
+        * our window and StructureNotify on socket->plug_window
+        */
        if (socket->plug_window && (xdwe->window == GDK_WINDOW_XWINDOW (socket->plug_window)))
          {
            GtkWidget *toplevel;
-
+           gboolean result;
+           
            GTK_NOTE(PLUGSOCKET,
                     g_message ("GtkSocket - destroy notify"));
            
@@ -1247,9 +1340,14 @@ gtk_socket_filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
              gtk_window_remove_embedded_xid (GTK_WINDOW (toplevel), xdwe->window);
            
            gdk_window_destroy_notify (socket->plug_window);
-           gtk_widget_destroy (widget);
-
+           g_object_unref (socket->plug_window);
            socket->plug_window = NULL;
+
+           g_object_ref (widget);
+           g_signal_emit (G_OBJECT (widget), socket_signals[PLUG_REMOVED], 0, &result);
+           if (!result)
+             gtk_widget_destroy (widget);
+           g_object_unref (widget);
            
            return_val = GDK_FILTER_REMOVE;
          }
@@ -1339,6 +1437,27 @@ gtk_socket_filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
          return_val = GDK_FILTER_REMOVE;
        }
       break;
+    case ReparentNotify:
+      {
+       XReparentEvent *xre = &xevent->xreparent;
+
+       if (!socket->plug_window && xre->parent == GDK_WINDOW_XWINDOW (widget->window))
+         {
+           gtk_socket_add_window (socket, xre->window, FALSE);
+           
+           if (socket->plug_window)
+             {
+               GTK_NOTE(PLUGSOCKET,
+                        g_message ("GtkSocket - window reparented",
+                                   socket->request_width,
+                                   socket->request_height));
+             }
+           
+           return_val = GDK_FILTER_REMOVE;
+         }
+       
+       break;
+      }
     case UnmapNotify:
       if (socket->plug_window &&
          xevent->xunmap.window == GDK_WINDOW_XWINDOW (socket->plug_window))
index 18a762bbe952aadb4147c9ae5eea0bcce0eb817b..14ee4165a13637d653c11aaf0720e2689b0e1269 100644 (file)
@@ -70,13 +70,23 @@ struct _GtkSocket
 struct _GtkSocketClass
 {
   GtkContainerClass parent_class;
+
+  gboolean (*plug_added)   (GtkSocket *socket);
+  gboolean (*plug_removed) (GtkSocket *socket);
 };
 
 
 GtkWidget*     gtk_socket_new      (void);
 GtkType        gtk_socket_get_type (void) G_GNUC_CONST;
-void           gtk_socket_steal    (GtkSocket *socket,
+
+void            gtk_socket_add_id (GtkSocket       *socket,
+                                  GdkNativeWindow  id);
+GdkNativeWindow gtk_socket_get_id (GtkSocket       *socket);
+
+#ifndef GTK_DISABLE_DEPRECATED
+void           gtk_socket_steal    (GtkSocket      *socket,
                                    GdkNativeWindow wid);
+#endif /* GTK_DISABLE_DEPRECATED */
 
 #ifdef __cplusplus
 }
index a25774438efdb4a0b08707a1cedcfdc9c904274c..ef4eb92246629e6204eae8170b9042e57958f34a 100644 (file)
@@ -682,7 +682,11 @@ gtk_tree_view_column_update_button (GtkTreeViewColumn *tree_column)
     {
       GTK_WIDGET_UNSET_FLAGS (tree_column->button, GTK_CAN_FOCUS);
       if (GTK_WIDGET_HAS_FOCUS (tree_column->button))
-       gtk_window_set_focus (GTK_WINDOW (gtk_widget_get_toplevel (tree_column->tree_view)), NULL);
+       {
+         GtkWidget *toplevel = gtk_widget_get_toplevel (tree_column->tree_view);
+         if (GTK_WIDGET_TOPLEVEL (toplevel))
+           gtk_window_set_focus (GTK_WINDOW (toplevel), NULL);
+       }
     }
 
   tree_column->dirty = TRUE;
index 295855b89f04eb566ac29c35f5b7a7bd9d19af98..29bf94167cd84170f088089c7c54029c45ddec14 100644 (file)
@@ -210,8 +210,6 @@ static void         gtk_widget_set_style_recurse            (GtkWidget        *widget,
                                                                 gpointer          client_data);
 static gint            gtk_widget_event_internal               (GtkWidget        *widget,
                                                                 GdkEvent         *event);
-static void            gtk_widget_propagate_hierarchy_changed  (GtkWidget        *widget,
-                                                                gpointer          client_data);
 static gboolean                gtk_widget_real_mnemonic_activate       (GtkWidget        *widget,
                                                                 gboolean          group_cycling);
 static void            gtk_widget_aux_info_destroy             (GtkWidgetAuxInfo *aux_info);
@@ -1500,7 +1498,7 @@ gtk_widget_unparent (GtkWidget *widget)
     {
       gtk_container_set_focus_child (GTK_CONTAINER (widget->parent), NULL);
 
-      if (GTK_IS_WINDOW (toplevel))
+      if (GTK_WIDGET_TOPLEVEL (toplevel))
        {
          GtkWidget *child;
       
@@ -1513,7 +1511,7 @@ gtk_widget_unparent (GtkWidget *widget)
            gtk_window_set_focus (GTK_WINDOW (toplevel), NULL);
        }
     }
-  if (GTK_IS_WINDOW (toplevel))
+  if (GTK_WIDGET_TOPLEVEL (toplevel))
     {
       GtkWidget *child;
       
@@ -1611,7 +1609,7 @@ gtk_widget_unparent (GtkWidget *widget)
   gtk_signal_emit (GTK_OBJECT (widget), widget_signals[PARENT_SET], old_parent);
   if (toplevel)
     {
-      gtk_widget_propagate_hierarchy_changed (widget, toplevel);
+      _gtk_widget_propagate_hierarchy_changed (widget, toplevel);
       g_object_unref (toplevel);
     }
       
@@ -3091,7 +3089,7 @@ gtk_widget_real_grab_focus (GtkWidget *focus_widget)
        * be set by the next loop.
        */
       toplevel = gtk_widget_get_toplevel (focus_widget);
-      if (GTK_IS_WINDOW (toplevel))
+      if (GTK_WIDGET_TOPLEVEL (toplevel))
        {
          widget = GTK_WINDOW (toplevel)->focus_widget;
          
@@ -3255,7 +3253,7 @@ gtk_widget_set_name (GtkWidget     *widget,
 
   g_object_notify (G_OBJECT (widget), "name");
 }
-
+s
 /**
  * gtk_widget_get_name:
  * @widget: a #GtkWidget
@@ -3471,7 +3469,7 @@ gtk_widget_set_parent (GtkWidget *widget,
 
   gtk_signal_emit (GTK_OBJECT (widget), widget_signals[PARENT_SET], NULL);
   if (GTK_WIDGET_ANCHORED (widget->parent))
-    gtk_widget_propagate_hierarchy_changed (widget, NULL);
+    _gtk_widget_propagate_hierarchy_changed (widget, NULL);
   g_object_notify (G_OBJECT (widget), "parent");
 }
 
@@ -3928,12 +3926,13 @@ gtk_widget_set_style_recurse (GtkWidget *widget,
 }
 
 static void
-gtk_widget_propagate_hierarchy_changed (GtkWidget      *widget,
-                                       gpointer         client_data)
+gtk_widget_propagate_hierarchy_changed_recurse (GtkWidget *widget,
+                                               gpointer   client_data)
 {
   gboolean new_anchored;
 
-  new_anchored = widget->parent && GTK_WIDGET_ANCHORED (widget->parent);
+  new_anchored = GTK_WIDGET_TOPLEVEL (widget) ||
+                 (widget->parent && GTK_WIDGET_ANCHORED (widget->parent));
 
   if (GTK_WIDGET_ANCHORED (widget) != new_anchored)
     {
@@ -3949,13 +3948,35 @@ gtk_widget_propagate_hierarchy_changed (GtkWidget       *widget,
   
       if (GTK_IS_CONTAINER (widget))
        gtk_container_forall (GTK_CONTAINER (widget),
-                             gtk_widget_propagate_hierarchy_changed,
-                             NULL);
+                             gtk_widget_propagate_hierarchy_changed_recurse,
+                             client_data);
       
       gtk_widget_unref (widget);
     }
 }
 
+/**
+ * _gtk_widget_propagate_hierarchy_changed:
+ * @widget: a #GtkWidget
+ * @previous_toplevel: Previous toplevel
+ * 
+ * Propagate changes in the anchored state to a widget and all
+ * children, unsetting or setting the ANCHORED flag, and
+ * emitting hierarchy_changed.
+ **/
+void
+_gtk_widget_propagate_hierarchy_changed (GtkWidget    *widget,
+                                        GtkWidget    *previous_toplevel)
+{
+  if (previous_toplevel)
+    g_object_ref (previous_toplevel);
+
+  gtk_widget_propagate_hierarchy_changed_recurse (widget, previous_toplevel);
+  
+  if (previous_toplevel)
+    g_object_unref (previous_toplevel);
+}
+
 void
 gtk_widget_reset_rc_styles (GtkWidget *widget)
 {
@@ -4556,14 +4577,16 @@ gtk_widget_set_extension_events (GtkWidget *widget,
  * seem unlikely, it actually happens when a GtkPlug is embedded
  * inside a GtkSocket within the same application
  * 
- * To reliably find for the toplevel GtkWindow, use
+ * To reliably find the toplevel GtkWindow, use
+ * gtk_widget_get_toplevel() and check if the TOPLEVEL flags
+ * is set on the result.
  * 
  *  GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
- *  if (GTK_IS_WINDOW (toplevel))
+ *  if (GTK_WIDGET_TOPLEVEL (toplevel))
  *   {
- *     /* Perform action on toplevel.
+ *     [ Perform action on toplevel. ]
  *   }
- * 
+ *
  * Return value: the topmost ancestor of @widget, or @widget itself if there's no ancestor
  **/
 GtkWidget*
index e8f525fe15f1a3471159ee2a22f9cd98a1edc231..03bae9dbbb8b21bc689710963e933f56860fde60 100644 (file)
@@ -733,8 +733,10 @@ void            gtk_requisition_free (GtkRequisition       *requisition);
 #  define gtk_widget_unref gtk_object_unref
 #endif /* GTK_TRACE_OBJECTS && __GNUC__ */
 
-GtkWidgetAuxInfo *_gtk_widget_get_aux_info (GtkWidget *widget,
-                                           gboolean   create);
+GtkWidgetAuxInfo *_gtk_widget_get_aux_info                (GtkWidget    *widget,
+                                                          gboolean      create);
+void              _gtk_widget_propagate_hierarchy_changed (GtkWidget    *widget,
+                                                          GtkWidget    *previous_toplevel);
 
 #ifdef __cplusplus
 }
index ab71501f1e397ba6da09c8ec639ccdf2df2fa362..55d0afa98063a59457dd904f9acb278744eb04ad 100644 (file)
@@ -1,12 +1,5 @@
 #include <gtk/gtk.h>
 
-#if defined (GDK_WINDOWING_X11)
-#include "x11/gdkx.h"
-#elif defined (GDK_WINDOWING_WIN32)
-#include "win32/gdkwin32.h"
-#define GDK_WINDOW_XWINDOW(w) (guint)GDK_WINDOW_HWND(w)
-#endif
-
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -14,9 +7,17 @@
 
 int n_children = 0;
 
+GSList *sockets = NULL;
+
 GtkWidget *window;
 GtkWidget *vbox;
-GtkWidget *lastsocket = NULL;
+
+typedef struct 
+{
+  GtkWidget *box;
+  GtkWidget *frame;
+  GtkWidget *socket;
+} Socket;
 
 extern guint32 create_child_plug (guint32  xid,
                                  gboolean local);
@@ -44,12 +45,78 @@ static GtkItemFactoryEntry menu_items[] =
   { "/File/_Quit",       "<control>Q", quit_cb,               0 },
 };
 
+static void
+socket_destroyed (GtkWidget *widget,
+                 Socket    *socket)
+{
+  sockets = g_slist_remove (sockets, socket);
+  g_free (socket);
+}
+
+static void
+plug_added (GtkWidget *widget,
+           Socket    *socket)
+{
+  g_print ("Plug added to socket\n");
+  
+  gtk_widget_show (socket->socket);
+  gtk_widget_hide (socket->frame);
+}
+
+static gboolean
+plug_removed (GtkWidget *widget,
+             Socket    *socket)
+{
+  g_print ("Plug removed from socket\n");
+  
+  gtk_widget_hide (socket->socket);
+  gtk_widget_show (socket->frame);
+  
+  return TRUE;
+}
+
+static Socket *
+create_socket (void)
+{
+  GtkWidget *label;
+  
+  Socket *socket = g_new (Socket, 1);
+  
+  socket->box = gtk_vbox_new (FALSE, 0);
+
+  socket->socket = gtk_socket_new ();
+  
+  gtk_box_pack_start (GTK_BOX (socket->box), socket->socket, TRUE, TRUE, 0);
+  
+  socket->frame = gtk_frame_new (NULL);
+  gtk_frame_set_shadow_type (GTK_FRAME (socket->frame), GTK_SHADOW_IN);
+  gtk_box_pack_start (GTK_BOX (socket->box), socket->frame, TRUE, TRUE, 0);
+  gtk_widget_show (socket->frame);
+  
+  label = gtk_label_new (NULL);
+  gtk_label_set_markup (GTK_LABEL (label), "<span color=\"red\">Empty</span>");
+  gtk_container_add (GTK_CONTAINER (socket->frame), label);
+  gtk_widget_show (label);
+
+  sockets = g_slist_prepend (sockets, socket);
+
+
+  g_signal_connect (G_OBJECT (socket->socket), "destroy",
+                   G_CALLBACK (socket_destroyed), socket);
+  g_signal_connect (G_OBJECT (socket->socket), "plug_added",
+                   G_CALLBACK (plug_added), socket);
+  g_signal_connect (G_OBJECT (socket->socket), "plug_removed",
+                   G_CALLBACK (plug_removed), socket);
+
+  return socket;
+}
+
 void
 steal (GtkWidget *window, GtkEntry *entry)
 {
   guint32 xid;
   const gchar *text;
-  GtkWidget *socket;
+  Socket *socket;
 
   text = gtk_entry_get_text (entry);
 
@@ -60,9 +127,9 @@ steal (GtkWidget *window, GtkEntry *entry)
       return;
     }
 
-  socket = gtk_socket_new ();
-  gtk_box_pack_start (GTK_BOX (vbox), socket, TRUE, TRUE, 0);
-  gtk_widget_show (socket);
+  socket = create_socket ();
+  gtk_box_pack_start (GTK_BOX (vbox), socket->box, TRUE, TRUE, 0);
+  gtk_widget_show (socket->box);
 
   gtk_socket_steal (GTK_SOCKET (socket), xid);
 }
@@ -70,9 +137,11 @@ steal (GtkWidget *window, GtkEntry *entry)
 void
 remove_child (GtkWidget *window)
 {
-  if (lastsocket)
-    gtk_widget_destroy (lastsocket);
-  lastsocket = NULL;
+  if (sockets)
+    {
+      Socket *socket = sockets->data;
+      gtk_widget_destroy (socket->box);
+    }
 }
 
 static gboolean
@@ -96,11 +165,11 @@ child_read_watch (GIOChannel *channel, GIOCondition cond, gpointer data)
        }
       else
        {
-         GtkWidget *socket = gtk_socket_new ();
-         gtk_box_pack_start (GTK_BOX (vbox), socket, TRUE, TRUE, 0);
-         gtk_widget_show (socket);
+         Socket *socket = create_socket ();
+         gtk_box_pack_start (GTK_BOX (vbox), socket->box, TRUE, TRUE, 0);
+         gtk_widget_show (socket->box);
          
-         gtk_socket_steal (GTK_SOCKET (socket), xid);
+         gtk_socket_add_id (GTK_SOCKET (socket->socket), xid);
        }
       g_free (line);
       return TRUE;
@@ -125,26 +194,22 @@ void
 add_child (GtkWidget *window,
           gboolean   active)
 {
-  GtkWidget *socket;
+  Socket *socket;
   char *argv[3] = { "./testsocket_child", NULL, NULL };
   char buffer[20];
   int out_fd;
   GIOChannel *channel;
   GError *error = NULL;
 
-  socket = gtk_socket_new ();
-  gtk_box_pack_start (GTK_BOX (vbox), socket, TRUE, TRUE, 0);
-  gtk_widget_show (socket);
-
-  lastsocket = socket;
-
   if (active)
     {
-      sprintf(buffer, "%#lx", GDK_WINDOW_XWINDOW (socket->window));
+      socket = create_socket ();
+      gtk_box_pack_start (GTK_BOX (vbox), socket->box, TRUE, TRUE, 0);
+      gtk_widget_show (socket->box);
+      sprintf(buffer, "%#lx", gtk_socket_get_id (GTK_SOCKET (socket->socket)));
       argv[1] = buffer;
     }
   
-#if 1
   if (!g_spawn_async_with_pipes (NULL, argv, NULL, 0, NULL, NULL, NULL, NULL, &out_fd, NULL, &error))
     {
       fprintf (stderr, "Can't exec testsocket_child: %s\n", error->message);
@@ -161,10 +226,6 @@ add_child (GtkWidget *window,
     }
   
   g_io_add_watch (channel, G_IO_IN | G_IO_HUP, child_read_watch, NULL);
-  
-#else
-  fprintf(stderr,"%s\n", buffer);
-#endif
 }
 
 void
@@ -182,15 +243,13 @@ add_passive_child (GtkWidget *window)
 void
 add_local_child (GtkWidget *window)
 {
-  GtkWidget *socket;
-
-  socket = gtk_socket_new ();
-  gtk_box_pack_start (GTK_BOX (vbox), socket, TRUE, TRUE, 0);
-  gtk_widget_show (socket);
+  Socket *socket;
 
-  lastsocket = socket;
+  socket = create_socket ();
+  gtk_box_pack_start (GTK_BOX (vbox), socket->box, TRUE, TRUE, 0);
+  gtk_widget_show (socket->box);
 
-  create_child_plug (GDK_WINDOW_XWINDOW (socket->window), TRUE);
+  create_child_plug (gtk_socket_get_id (GTK_SOCKET (socket->socket)), TRUE);
 }
 
 int